
 


 
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico">
 
 <script type="text/javascript">
 
 
 
 var codesite_token = "55b122417e72b952b1b3411d91b5d902";
 
 
 var logged_in_user_email = "efhennum@gmail.com";
 
 
 var relative_base_url = "";
 
 </script>
 
 
 <title>WritingScenarios - 
 xspec -
 
 How to write XSpec scenarios - Project Hosting on Google Code</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
 
 <meta name="ROBOTS" content="NOARCHIVE">
 
 <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/14756227129406843427/css/ph_core.css">
 
 <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/14756227129406843427/css/ph_detail.css" >
 
 
 
 <link type="application/atom+xml" rel="alternate" href="/feeds/p/xspec/svnchanges/basic?path=/wiki/WritingScenarios.wiki">
 
 
<!--[if IE]>
 <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/14756227129406843427/css/d_ie.css" >
<![endif]-->
 <style type="text/css">
 .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
 .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
 .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
 </style>
</head>
<body class="t6">
 <script type="text/javascript">
 var _gaq = _gaq || [];
 _gaq.push(
 ['siteTracker._setAccount', 'UA-18071-1'],
 ['siteTracker._trackPageview']);
 
 _gaq.push(
 ['projectTracker._setAccount', 'UA-5548232-1'],
 ['projectTracker._trackPageview']);
 
 (function() {
 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
 })();
 </script>
 <div id="gaia">
 
 <span>
 
 
 <b>efhennum@gmail.com</b>
 
 
 | <a href="/u/efhennum/" id="projects-dropdown" onclick="return false;"
 ><u>My favorites</u> <small>&#9660;</small></a>
 | <a href="/u/efhennum/" onclick="_CS_click('/gb/ph/profile');" 
 title="Profile, Updates, and Settings"
 ><u>Profile</u></a>
 | <a href="https://www.google.com/accounts/Logout?continue=http%3A%2F%2Fcode.google.com%2Fp%2Fxspec%2Fwiki%2FWritingScenarios" 
 onclick="_CS_click('/gb/ph/signout');"
 ><u>Sign out</u></a>
 
 </span>

 </div>
 <div class="gbh" style="left: 0pt;"></div>
 <div class="gbh" style="right: 0pt;"></div>
 
 
 <div style="height: 1px"></div>
<!--[if IE 6]>
<div style="text-align:center;">
Support browsers that contribute to open source, try <a href="http://www.firefox.com">Firefox</a> or <a href="http://www.google.com/chrome">Google Chrome</a>.
</div>
<![endif]-->




 <table style="padding:0px; margin: 20px 0px 0px 0px; width:100%" cellpadding="0" cellspacing="0">
 <tr style="height: 58px;">
 
 <td style="width: 55px; text-align:center;">
 <a href="/p/xspec/">
 
 <img src="http://www.gstatic.com/codesite/ph/images/defaultlogo.png" alt="Logo">
 
 </a>
 </td>
 
 <td style="padding-left: 0.5em">
 
 <div id="pname" style="margin: 0px 0px -3px 0px">
 <a href="/p/xspec/" style="text-decoration:none; color:#000">xspec</a>
 
 </div>
 <div id="psum">
 <i><a id="project_summary_link" href="/p/xspec/" style="text-decoration:none; color:#000">BDD framework for XSLT</a></i>
 </div>
 
 </td>
 <td style="white-space:nowrap;text-align:right">
 
 <form action="/hosting/search">
 <input size="30" name="q" value="">
 <input type="submit" name="projectsearch" value="Search projects" >
 </form>
 
 </tr>
 </table>


 
<table id="mt" cellspacing="0" cellpadding="0" width="100%" border="0">
 <tr>
 <th onclick="if (!cancelBubble) _go('/p/xspec/');">
 <div class="tab inactive">
 <div class="round4"></div>
 <div class="round2"></div>
 <div class="round1"></div>
 <div class="box-inner">
 <a onclick="cancelBubble=true;" href="/p/xspec/">Project&nbsp;Home</a>
 </div>
 </div>
 </th><td>&nbsp;&nbsp;</td>
 
 
 
 
 <th onclick="if (!cancelBubble) _go('/p/xspec/downloads/list');">
 <div class="tab inactive">
 <div class="round4"></div>
 <div class="round2"></div>
 <div class="round1"></div>
 <div class="box-inner">
 <a onclick="cancelBubble=true;" href="/p/xspec/downloads/list">Downloads</a>
 </div>
 </div>
 </th><td>&nbsp;&nbsp;</td>
 
 
 
 
 
 <th onclick="if (!cancelBubble) _go('/p/xspec/w/list');">
 <div class="tab active">
 <div class="round4"></div>
 <div class="round2"></div>
 <div class="round1"></div>
 <div class="box-inner">
 <a onclick="cancelBubble=true;" href="/p/xspec/w/list">Wiki</a>
 </div>
 </div>
 </th><td>&nbsp;&nbsp;</td>
 
 
 
 
 
 <th onclick="if (!cancelBubble) _go('/p/xspec/issues/list');">
 <div class="tab inactive">
 <div class="round4"></div>
 <div class="round2"></div>
 <div class="round1"></div>
 <div class="box-inner">
 <a onclick="cancelBubble=true;" href="/p/xspec/issues/list">Issues</a>
 </div>
 </div>
 </th><td>&nbsp;&nbsp;</td>
 
 
 
 
 
 <th onclick="if (!cancelBubble) _go('/p/xspec/source/checkout');">
 <div class="tab inactive">
 <div class="round4"></div>
 <div class="round2"></div>
 <div class="round1"></div>
 <div class="box-inner">
 <a onclick="cancelBubble=true;" href="/p/xspec/source/checkout">Source</a>
 </div>
 </div>
 </th><td>&nbsp;&nbsp;</td>
 
 
 <td width="100%">&nbsp;</td>
 </tr>
</table>
<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
 <tr>
 
 
 
 <td>
 <div class="issueDetail">
<div class="isf">
 
 <span class="inIssueList"> 
 <span>Search</span>
 <form action="/p/xspec/w/list" method="GET" style="display:inline">
 <select id="can" name="can" style="font-size:92%">
 <option disabled="disabled">Search within:</option>
 
 <option value="1" >&nbsp;All wiki pages</option>
 <option value="3" >&nbsp;Featured pages</option>
 <option value="2" selected="selected">&nbsp;Current pages</option>
 
 
 <option value="5" {is can "5"}selected="selected"{end}>&nbsp;My starred pages</option>
 
 <option value="4" >&nbsp;Deprecated pages</option>
 
 </select>
 <span>for</span>
 <span id="qq"><input type="text" size="38" id="searchq" name="q" value=""
 autocomplete="off" style="font-size:92%" ></span>
 
 
 <input type="submit" value="Search" style="font-size:92%" >
 </form>
 </span>

 
 
 
 
 
 
 

</div>
</div>

 </td>
 
 
 
 
 
 
 <td height="4" align="right" valign="top" class="bevel-right">
 <div class="round4"></div>
 <div class="round2"></div>
 <div class="round1"></div>
 </td>
 </tr>
</table>
<script type="text/javascript">
 var cancelBubble = false;
 function _go(url) { document.location = url; }
</script>


<div id="maincol"
 
>

 
<!-- IE -->







 <style type="text/css">
 .artifactcomment {
 margin: .5em 0 0 0;
 padding: .3em 0 .3em .3em;
 border-top: 3px solid #c3d9ff;
 }
 #commentlist {
 border-bottom: 3px solid #c3d9ff;
 }
 #commentform { padding-top: 1em; }
 .delcom { background: #e8e8e8 }
 .commentcontent { margin: 1em 0;}
 </style>


 <div id="wikicontent">
 <table width="100%" border="0" cellspacing="0" cellpadding="0">
 <tr>
 
 <td class="vt" id="wikimaincol" width="100%">
 
 <div style="float:right; width:18em" id="wikimeta">
 <div class="pmeta_bubble_bg">
 <div class="round4"></div>
 <div class="round2"></div>
 <div class="round1"></div>
 <div class="box-inner">
 <table style="padding: 5px">
 <tr><td colspan="2" style="padding-bottom:5px">Updated <span title="Mon Feb  1 16:35:28 2010">Feb 01, 2010</span>
 
 by <a style="white-space: nowrap" href="/u/@VBFSR1dQDhZMWQZ%2F/">fgeor...@gmail.com</a>
 </td></tr>
 
 <tr><th class="vt">Labels:</th>
 <td>
 
 <a href="/p/xspec/w/list?q=label:Phase-Deploy"
 title="How to install and configure the program"
 >Phase-Deploy</a>
 
 </td>
 </tr>
 
 
 </table>
 </div>
 <div class="round1"></div>
 <div class="round2"></div>
 <div class="round4"></div>
 </div>
 </div>
 
 <div id="wikiheader" style="margin-bottom:1em">
 
 <img width="15" height="15" id="star_img"
 src="http://www.gstatic.com/codesite/ph/images/star_off.gif"
 style="cursor:pointer"
 
 onclick="_CS_toggleStar(this,
 '',
 {'scope': 'wiki',
 'user': '_CURRENT_USER',
 'item': 'xspec:WritingScenarios',
 'token': codesite_token
 });"/>
 
 &nbsp;
 <span style="font-size:120%;font-weight:bold">WritingScenarios</span>
 &nbsp;
 
 
 <div style="font-style:italic; margin-top: 3px">How to write XSpec scenarios</div>
 
 </div>
 <h1><a name="Contents"/>Contents<a href="#Contents" class="section_anchor">&para;</a></h1><p><ul><li><a href="#Contents">Contents</a></li><li><a href="#Introduction">Introduction</a></li><li><a href="#Matching_Scenarios">Matching Scenarios</a></li><li><a href="#Function_Scenarios">Function Scenarios</a></li><li><a href="#Named_Scenarios">Named Scenarios</a></li><li><a href="#Expectations">Expectations</a></li><li><a href="#Nesting_Scenarios">Nesting Scenarios</a></li><li><a href="#Focusing_Your_Efforts">Focusing Your Efforts</a></li><li><a href="#Global_Parameters">Global Parameters</a></li></ul> </p><h1><a name="Introduction"/>Introduction<a href="#Introduction" class="section_anchor">&para;</a></h1><p>The description of the behaviour of a stylesheet lives within an XSpec document, which should adhere to the <a href="http://code.google.com/p/xspec/source/browse/trunk/xspec.rnc" rel="nofollow">XSpec RELAX NG schema</a>. All elements are in the <tt>http://www.jenitennison.com/xslt/xspec</tt> namespace, which is bound to <tt>x</tt> in these examples. </p><p>The document element is a <tt>&lt;x:description&gt;</tt> element, whose <tt>stylesheet</tt> attribute holds a relative URI pointing to the stylesheet that the XSpec document describes. You can also specify: </p><ul><li>a <tt>version</tt> attribute that gives the version of the stylesheet the XSpec document describes </li><li>a <tt>xslt-version</tt> attribute that gives the version of XSLT the stylesheet uses; if you don&#x27;t specify it, this defaults to 2.0 </li></ul><p>The <tt>&lt;x:description&gt;</tt> element contains a number of <tt>&lt;x:scenario&gt;</tt> elements, each of which describes a particular scenario that&#x27;s being tested. Each <tt>&lt;x:scenario&gt;</tt> element has a <tt>label</tt> attribute that describes the scenario in human language. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when processing a para element&quot;&gt;
  ...
&lt;/x:scenario&gt;</pre><p>Scenarios fall into three main types: </p><ul><li><strong><a href="#Matching_Scenarios">matching scenarios</a></strong> describe the result of applying templates to a node in a particular mode (and with particular parameters) </li><li><strong><a href="#Function_Scenarios">function scenarios</a></strong> describe the results of calling a particular function with particular arguments </li><li><strong><a href="#Named_Scenarios">named scenarios</a></strong> describe the results of calling a particular named template with particular parameters </li></ul><h1><a name="Matching_Scenarios"/>Matching Scenarios<a href="#Matching_Scenarios" class="section_anchor">&para;</a></h1><p>Matching scenarios hold a <tt>&lt;x:context&gt;</tt> element that describes a node to apply templates to. The context can be supplied in two main ways: </p><ul><li>you can point to a node in an existing document by giving the document URI in the <tt>href</tt> attribute and, if you want, selecting a particular node by putting a path in the <tt>select</tt> attribute </li><li>you can embed XML within the <tt>&lt;x:context&gt;</tt> element; the content becomes the context node, although you can also select a node within that XML using the <tt>select</tt> attribute </li></ul><p>The first method is useful if you already have example XML documents that you want to use as the basis of your testing. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when processing a para element&quot;&gt;
  &lt;x:context href=&quot;source/test.xml&quot; select=&quot;/doc/body/p[1]&quot; /&gt;
  ...
&lt;/x:scenario&gt;</pre><p>The second method is related to the concept of a <a href="http://en.wikipedia.org/wiki/Mock_object" rel="nofollow">mock object</a>: it is an example of some XML which you have created simply for testing purposes. The XML might not be legal; it only needs to have the attributes or content necessary for the particular behaviour that needs to be tested. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when processing a para element&quot;&gt;
  &lt;x:context&gt;
    &lt;para&gt;...&lt;/para&gt;
  &lt;/x:context&gt;
  ...
&lt;/x:scenario&gt;</pre><p>The <tt>&lt;x:context&gt;</tt> element can also have a <tt>mode</tt> attribute that supplies the mode to apply templates in. </p><h1><a name="Function_Scenarios"/>Function Scenarios<a href="#Function_Scenarios" class="section_anchor">&para;</a></h1><p>Function scenarios hold a <tt>&lt;x:call&gt;</tt> element with a <tt>function</tt> attribute whose content is a qualified name that is the same as the qualified name of the function you want to call. The <tt>&lt;x:call&gt;</tt> element should hold a number of <tt>&lt;x:param&gt;</tt> elements, one for each of the arguments to the function. </p><p>The <tt>&lt;x:param&gt;</tt> elements can specify node values in the same way as the <tt>&lt;x:context&gt;</tt> element gets set (described above), or simply by giving a <tt>select</tt> attribute which holds an XPath that specifies the value. You can specify a <tt>name</tt> or <tt>position</tt> attribute for each of the <tt>&lt;x:param&gt;</tt> elements; if you don&#x27;t, the order in which they&#x27;re specified will determine the order in which they&#x27;re given in the function call. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when capitalising a string&quot;&gt;
  &lt;x:call function=&quot;eg:capital-case&quot;&gt;
    &lt;x:param select=&quot;&#x27;an example string&#x27;&quot; /&gt;
    &lt;x:param select=&quot;true()&quot; /&gt;
  &lt;/x:call&gt;
  ...
&lt;/x:scenario&gt;</pre><p>will result in the call <tt>eg:capital-case(&#x27;an example string&#x27;, false())</tt> as will: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when capitalising a string&quot;&gt;
  &lt;x:call function=&quot;eg:capital-case&quot;&gt;
    &lt;x:param select=&quot;true()&quot; position=&quot;2&quot; /&gt;
    &lt;x:param select=&quot;&#x27;an example string&#x27;&quot; position=&quot;1&quot; /&gt;
  &lt;/x:call&gt;
  ...
&lt;/x:scenario&gt;</pre><h1><a name="Named_Scenarios"/>Named Scenarios<a href="#Named_Scenarios" class="section_anchor">&para;</a></h1><p>Named template scenarios are similar to function scenarios except that the <tt>&lt;x:call&gt;</tt> element takes a <tt>template</tt> attribute rather than a <tt>function</tt> attribute, and the <tt>&lt;x:param&gt;</tt> elements within it must have a <tt>name</tt> attribute that supplies the name of the parameter. These parameters can also have a <tt>tunnel</tt> attribute to indicate a tunnel parameter. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when creating a table with two columns containing three values&quot;&gt;
  &lt;x:call template=&quot;createTable&quot;&gt;
    &lt;x:param name=&quot;nodes&quot;&gt;
      &lt;value&gt;A&lt;/value&gt;
      &lt;value&gt;B&lt;/value&gt;
      &lt;value&gt;C&lt;/value&gt;
    &lt;/x:param&gt;
    &lt;x:param name=&quot;cols&quot; select=&quot;2&quot; /&gt;
  &lt;/x:call&gt;
  ...
&lt;/x:scenario&gt;</pre><p>In fact, you can use <tt>&lt;x:param&gt;</tt> in the same way within the <tt>&lt;x:context&gt;</tt> element in matching scenarios. </p><h1><a name="Expectations"/>Expectations<a href="#Expectations" class="section_anchor">&para;</a></h1><p>Each scenario can have one or more &quot;expectations&quot;: things that should be true of the result of the function or template invocation described by the scenario. Each expectation is specified with an <tt>&lt;x:expect&gt;</tt> element. The <tt>label</tt> attribute on the <tt>&lt;x:expect&gt;</tt> element gives a human-readable description of the expectation. </p><p>There are two main kinds of expectations: </p><ul><li>a value that the result should match, which may be </li><ul><li>an atomic value </li><li>an XML snippet </li></ul><li>an arbitrary XPath test that should be true of the result </li></ul><p>To specify an atomic value, use the <tt>select</tt> attribute on the <tt>&lt;x:expect&gt;</tt> element. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when capitalising a string&quot;&gt;
  &lt;x:call function=&quot;eg:capital-case&quot;&gt;
    &lt;x:param select=&quot;&#x27;an example string&#x27;&quot; /&gt;
    &lt;x:param select=&quot;true()&quot; /&gt;
  &lt;/x:call&gt;
  &lt;x:expect label=&quot;it should capitalise every word in the string&quot; select=&quot;&#x27;An Example String&#x27;&quot; /&gt;
&lt;/x:scenario&gt;</pre><p>To specify some XML, put it within the <tt>&lt;x:expect&gt;</tt> element. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when processing a para element&quot;&gt;
  &lt;x:context&gt;
    &lt;para&gt;...&lt;/para&gt;
  &lt;/x:context&gt;
  &lt;x:expect label=&quot;it should produce a p element&quot;&gt;
    &lt;p&gt;...&lt;/p&gt;
  &lt;/x:expect&gt;
&lt;/x:scenario&gt;</pre><p>One thing to note here is that when comparing the actual result with the expected result, three dots in an element or attribute value within the expected XML means that the values aren&#x27;t compared. If the actual result is: </p><pre class="prettyprint">  &lt;p&gt;A sample para&lt;/p&gt;</pre><p>and the expected result is given as: </p><pre class="prettyprint">  &lt;p&gt;...&lt;/p&gt;</pre><p>then these match. If the expected result is: </p><pre class="prettyprint">  &lt;p&gt;Some other para&lt;/p&gt;</pre><p>then they don&#x27;t. </p><p>To specify an arbitrary XPath test, use the <tt>test</tt> attribute on <tt>&lt;x:expect&gt;</tt>. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when creating a table with two columns containing three values&quot;&gt;
  &lt;x:call template=&quot;createTable&quot;&gt;
    &lt;x:param name=&quot;nodes&quot;&gt;
      &lt;value&gt;A&lt;/value&gt;
      &lt;value&gt;B&lt;/value&gt;
      &lt;value&gt;C&lt;/value&gt;
    &lt;/x:param&gt;
    &lt;x:param name=&quot;cols&quot; select=&quot;2&quot; /&gt;
  &lt;/x:call&gt;
  &lt;x:expect label=&quot;the resulting table should have two columns&quot;
    test=&quot;count(/table/colspec/col) = 2&quot; /&gt;
&lt;/x:scenario&gt;</pre><p>Within the XPath expression, you can use the variable <tt>$x:result</tt> to access the result of the test (i.e. the result of calling the function or the template, or of applying the template rule).  In addition, if the result is a sequence of nodes, it is wrapped in a document node and this document is set as the context node of the expression. </p><p>You can also combine the <tt>test</tt> attribute with the content of the <tt>&lt;x:expect&gt;</tt> element if you want to just test a portion of the result. For example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when creating a table with two columns containing three values&quot;&gt;
  &lt;x:call template=&quot;createTable&quot;&gt;
    &lt;x:param name=&quot;nodes&quot;&gt;
      &lt;value&gt;A&lt;/value&gt;
      &lt;value&gt;B&lt;/value&gt;
      &lt;value&gt;C&lt;/value&gt;
    &lt;/x:param&gt;
    &lt;x:param name=&quot;cols&quot; select=&quot;2&quot; /&gt;
  &lt;/x:call&gt;
  &lt;x:expect label=&quot;the resulting table should have two columns&quot;
    test=&quot;count(/table/colspec/col) = 2&quot; /&gt;
  &lt;x:expect label=&quot;the first row should contain the first two values&quot;
    test=&quot;/table/tbody/tr[1]&quot;&gt;
    &lt;tr&gt;
      &lt;td&gt;A&lt;/td&gt;&lt;td&gt;B&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/x:expect&gt;
&lt;/x:scenario&gt;</pre><h1><a name="Nesting_Scenarios"/>Nesting Scenarios<a href="#Nesting_Scenarios" class="section_anchor">&para;</a></h1><p>You can nest scenarios inside each other. The nested scenarios inherit the context or call from its ancestor scenarios. All the scenarios in a particular tree have to be of the same type (matching, function or named). Usually only the lowest level of the scenarios will contain any expectations. Here&#x27;s an example: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when creating a table&quot;&gt;
  &lt;x:call template=&quot;createTable&quot; /&gt;
  &lt;x:scenario label=&quot;holding three values&quot;&gt;
    &lt;x:call&gt;
      &lt;x:param name=&quot;nodes&quot;&gt;
        &lt;value&gt;A&lt;/value&gt;
        &lt;value&gt;B&lt;/value&gt;
        &lt;value&gt;C&lt;/value&gt;
      &lt;/x:param&gt;
    &lt;/x:call&gt;
    &lt;x:scenario label=&quot;in two columns&quot;&gt;
      &lt;x:call&gt;
        &lt;x:param name=&quot;cols&quot; select=&quot;2&quot; /&gt;
      &lt;/x:call&gt;
      &lt;x:expect label=&quot;the resulting table should have two columns&quot;
        test=&quot;count(/table/colspec/col) = 2&quot; /&gt;
      &lt;x:expect label=&quot;the first row should contain the first two values&quot;
        test=&quot;/table/tbody/tr[1]&quot;&gt;
        &lt;tr&gt;
          &lt;td&gt;A&lt;/td&gt;&lt;td&gt;B&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/x:expect&gt;
    &lt;/x:scenario&gt;
    ... other scenarios around creating tables with three values (with different numbers of columns) ...
  &lt;/x:scenario&gt;
  ... other scenarios around creating tables ...
&lt;/x:scenario&gt;</pre><p>When you create scenarios like this, the labels of the nested scenarios are concatenated to create the label for the scenario. In the above example, the third scenario has the label &quot;when creating a table holding three values in two columns&quot;. </p><h1><a name="Focusing_Your_Efforts"/>Focusing Your Efforts<a href="#Focusing_Your_Efforts" class="section_anchor">&para;</a></h1><p>XSpec descriptions can get quite large, which can mean that running the tests takes some time. There are three ways of dealing with this. </p><p>First, you can import other XSpec description documents into your main one using <tt>&lt;x:import&gt;</tt>. The <tt>href</tt> attribute holds the location of the imported document. All the scenarios from the referenced document are imported into this one, and will be run when you execute it. For example: </p><pre class="prettyprint">&lt;x:import href=&quot;other_xspec.xml&quot; /&gt;</pre><p>It helps if the imported XSpec description documents can stand alone; this enables you to perform a subset of the tests. To work effectively, you&#x27;ll want the imported XSpec description documents to cover the same stylesheet as the main one, or a stylesheet module that&#x27;s included or imported into that stylesheet. </p><p>Second, you can mark any scenario or expectation as &quot;pending&quot; by wrapping them within a <tt>&lt;x:pending&gt;</tt> element or adding a <tt>pending</tt> attribute to the <tt>&lt;x:scenario&gt;</tt> element. When the tests are run, any pending scenarios or expectations aren&#x27;t tested (though they still appear, greyed out, in the test report). The <tt>&lt;x:pending&gt;</tt> element can have a <tt>label</tt> attribute to describe why the particular description is pending; for example it might hold &quot;TODO&quot;. If you use the <tt>pending</tt> attribute, its value should give the reason the tests are pending. For example: </p><pre class="prettyprint">&lt;x:pending label=&quot;no support for block elements yet&quot;&gt;
  &lt;x:scenario label=&quot;when processing a para element&quot;&gt;
    &lt;x:context&gt;
      &lt;para&gt;...&lt;/para&gt;
    &lt;/x:context&gt;
    &lt;x:expect label=&quot;it should produce a p element&quot;&gt;
      &lt;p&gt;...&lt;/p&gt;
    &lt;/x:expect&gt;
  &lt;/x:scenario&gt;
&lt;/x:pending&gt;</pre><p>or: </p><pre class="prettyprint">&lt;x:scenario pending=&quot;no support for block elements yet&quot; label=&quot;when processing a para element&quot;&gt;
  &lt;x:context&gt;
    &lt;para&gt;...&lt;/para&gt;
  &lt;/x:context&gt;
  &lt;x:expect label=&quot;it should produce a p element&quot;&gt;
    &lt;p&gt;...&lt;/p&gt;
  &lt;/x:expect&gt;
&lt;/x:scenario&gt;</pre><p>Third, you can mark any scenario as having the current &quot;focus&quot; by adding a <tt>focus</tt> attribute to a <tt>&lt;x:scenario&gt;</tt> element. Effectively, this marks every <i>other</i> scenario as &quot;pending&quot;, with the label given as the value of the <tt>focus</tt> attribute. For example: </p><pre class="prettyprint">&lt;x:scenario focus=&quot;getting capitalisation working&quot; label=&quot;when capitalising a string&quot;&gt;
  &lt;x:call function=&quot;eg:capital-case&quot;&gt;
    &lt;x:param select=&quot;&#x27;an example string&#x27;&quot; /&gt;
    &lt;x:param select=&quot;true()&quot; /&gt;
  &lt;/x:call&gt;
  &lt;x:expect label=&quot;it should capitalise every word in the string&quot; select=&quot;&#x27;An Example String&#x27;&quot; /&gt;
&lt;/x:scenario&gt;</pre><blockquote><i>Using focus is a good way of working through one particular scenario, but once your code is working with that  
scenario, you should always test all the others again, just in case you&#x27;ve broken something else.</i> 
</blockquote><h1><a name="Global_Parameters"/>Global Parameters<a href="#Global_Parameters" class="section_anchor">&para;</a></h1><p>You can put <tt>&lt;x:param&gt;</tt> elements at the top level of the XSpec description document (as a child of the <tt>&lt;x:description&gt;</tt> element). These effectively override any global parameters or variables that you have declared in your stylesheet. They are set in just the same way as setting parameters when testing <a href="#Named_Scenarios">named templates</a> or <a href="#Function_Scenarios">functions</a>. </p><blockquote><i>With the current XSLT-based implementation, it isn&#x27;t possible to have different scenarios use different values 
for global parameters. Hopefully that will come with an XProc-based implementation. Testing is made easier if 
you declare local parameters on any templates or functions that use global parameters; these can default to 
the value of the global parameter, but be set explicitly when testing. For example, if <tt>$tableClass</tt> is a global 
parameter, you might do</i> 
</blockquote><pre class="prettyprint">    &lt;xsl:template name=&quot;createTable&quot;&gt;
      &lt;xsl:param name=&quot;nodes&quot; as=&quot;node()+&quot; required=&quot;yes&quot; /&gt;
      &lt;xsl:param name=&quot;cols&quot; as=&quot;xs:integer&quot; required=&quot;yes&quot; /&gt;
      &lt;xsl:param name=&quot;tableClass&quot; as=&quot;xs:string&quot; select=&quot;$tableClass&quot; /&gt;
      ...
    &lt;/xsl:template&gt;</pre><blockquote><i>to enable the full testing of the <tt>createTable</tt> template.</i> 
</blockquote>
 </td> 
 </tr>
 </table>
 </div>


 
 <br>
 


 
 
 
 
 
 
 
 
 
 
 
 
 

<div class="collapse">


 


<div id="commentlist">

 
 <div class="artifactcomment"
 
 >
 
 
 
 
 
 
 <span class="author">Comment
 
 by
 
 <a style="white-space: nowrap" href="/u/jsulak/">jsulak</a>,
 
 </span>
 <span class="date" title="Wed Oct  8 07:54:04 2008">Oct 08, 2008</span>
 <div>
<div class="commentcontent">
<p>One thing to watch out for when using mock objects is namespaces.  In this example  </p><p>{{{&lt;scenario label=&quot;when processing a para element&quot;&gt; <blockquote>&lt;context&gt; 
<blockquote>&lt;para&gt;...&lt;/para&gt; 
</blockquote>&lt;/context&gt; 
... 
</blockquote>&lt;/scenario&gt;}}} </p><p>the XSpec elements and the &lt;para&gt; elements are both in the same namespace. If you were to run this test, it would fail (unless of course your test document was also using the XSpec namespace).  Using a namespace prefix for XSpec elements fixes the problem. </p>
</div>
 
 
 </div>
 </div>
 

 
 <div class="artifactcomment"
 
 >
 
 
 
 
 
 
 <span class="author">Comment
 
 by
 
 <a style="white-space: nowrap" href="/u/@WRhXS1VSAhhMXwc%3D/">wap...@mulberrytech.com</a>,
 
 </span>
 <span class="date" title="Tue Mar 24 14:03:34 2009">Mar 24, 2009</span>
 <div>
<div class="commentcontent">
<p>Any tips on how to express that there should be no results? </p><p>For example, I have input </p><pre class="prettyprint">&lt;p&gt;  &lt;/p&gt;</pre><p>(That is, a <tt>p</tt> with whitespace only.) </p><p>My specification says this element should be dropped. </p><p>Is there any way to XSpec this? </p>
</div>
 
 
 </div>
 </div>
 

 
 <div class="artifactcomment"
 
 >
 
 
 
 
 
 
 <span class="author">Comment
 
 by
 
 <a style="white-space: nowrap" href="/u/jeni.tennison/">jeni.tennison</a>,
 
 </span>
 <span class="date" title="Tue Mar 24 14:21:58 2009">Mar 24, 2009</span>
 <div>
<div class="commentcontent">
<p>Yes. You expect the scenario to result in an empty sequence. So you can do: </p><pre class="prettyprint">&lt;x:scenario label=&quot;when processing whitespace-only paragraphs&quot;&gt;
  &lt;x:context&gt;
    &lt;p xml:space=&quot;preserve&quot;&gt;    &lt;/p&gt;
  &lt;/x:context&gt;
  &lt;x:expect label=&quot;it shouldn&#x27;t produce anything&quot; select=&quot;()&quot; /&gt;
&lt;/x:scenario&gt;</pre>
</div>
 
 
 </div>
 </div>
 

 
 <div class="artifactcomment"
 
 >
 
 
 
 
 
 
 <span class="author">Comment
 
 by
 
 <a style="white-space: nowrap" href="/u/@WRhXS1VSAhhMXwc%3D/">wap...@mulberrytech.com</a>,
 
 </span>
 <span class="date" title="Wed Mar 25 14:46:37 2009">Mar 25, 2009</span>
 <div>
<div class="commentcontent">
<p>Cool. :-) I tried <tt>empty(.)</tt> and it didn&#x27;t (appear to) work. I think I&#x27;m mystified about the evaluation context of the result test. </p>
</div>
 
 
 </div>
 </div>
 

 
 <div class="artifactcomment"
 
 >
 
 
 
 
 
 
 <span class="author">Comment
 
 by
 
 <a style="white-space: nowrap" href="/u/@UBNfQ1BRAhhMWQN0/">cms...@blackmesatech.com</a>,
 
 </span>
 <span class="date" title="Thu Nov  5 16:13:31 2009">Nov 05, 2009</span>
 <div>
<div class="commentcontent">
<p>It might be helpful to mention that when an XML snippet is given as the content of &#x27;expect&#x27; it needs to have a single root.  (At least, in the current implementation the snippet is made into the content of an xsl:document element, and comparisons did not work when I wrote a context that selected several nodes and an expected result of two elements with specified content.  Revising to make each test select one node and produce one element, or nothing, seems to have solved the problem.)   </p>
</div>
 
 
 </div>
 </div>
 

 
 <div class="artifactcomment"
 
 >
 
 
 
 
 
 
 <span class="author">Comment
 
 by
 
 <a style="white-space: nowrap" href="/u/@UBBfR1NSARBGVwV7FA%3D%3D/">chriztia...@gmail.com</a>,
 
 </span>
 <span class="date" title="Mon Nov 23 14:56:04 2009">Nov 23, 2009</span>
 <div>
<div class="commentcontent">
<p>I had a problem with a an expectation test that didn&#x27;t seem to work: </p><pre class="prettyprint">&lt;x:expect label=&quot;it should add &#x27;contain&#x27; to the class attribute&quot; test=&quot;contains(/div/@class, &#x27;contain&#x27;)&quot; /&gt;</pre><p>- report said: &quot;Expected Result - ()&quot;, whereas if I wrote the test like this: </p><pre class="prettyprint">&lt;x:expect label=&quot;it should add &#x27;contain&#x27; to the class attribute&quot; test=&quot;/div[contains(@class, &#x27;contain&#x27;)]&quot; /&gt;</pre><p>- it worked like a charm... </p>
</div>
 
 
 </div>
 </div>
 

</div>
</div>

 


 <script type="text/javascript">
 function delComment(sequence_num, create_time, delete_mode) {
 var f = document.forms["delcom"];
 f.sequence_num.value = sequence_num;
 f.create_time.value = create_time;
 f.mode.value = delete_mode;
 f.submit();
 return false;
 }
 </script>


 
 
 
 
 
 <div id="commentform">
 <form action="../w/detail.do" method="post">
 <table>
 <tr><td class="vt">
 <input type="hidden" name="pagename" value="WritingScenarios" >
 <input type="hidden" name="token" value="55b122417e72b952b1b3411d91b5d902" >
 <div>Enter a comment:</div>
 <textarea name="content" rows="6" cols="80"></textarea><br><br>
 <input type="submit" name="submit" value="Submit" >
 </td>
 <td class="vt">
 <div id="whb" class="tip" style="width:15em">
 <div class="round4"></div>
 <div class="round2"></div>
 <div class="round1"></div>
 <div class="box-inner closed"
 id="entrybubble">
 <a class="ifClosed" href="#whb" style="float:right"
 onclick="_toggleHidden(this); document.getElementById('wikihelp').value='opened'">show</a>
 <a class="ifOpened" href="#whb" style="float:right"
 onclick="_toggleHidden(this); document.getElementById('wikihelp').value='closed'"
 >hide</a>
 <b>Wiki markup help</b>
 <div class="ifOpened">
 <div style="padding:2px; font-size:96%">
 =Heading1=<br>
 ==Heading2==<br>
 ===Heading3===<br>
 <br>
 *bold* &nbsp; &nbsp;
 _italic_<br>
 `inline code`<br>
 escape: `*`<br>
 <br>
 Indent lists 2 spaces:<br>
 &nbsp;&nbsp;* bullet item<br>
 &nbsp;&nbsp;# numbered list<br>
 <br>
 {{{<br>
 verbatim code block<br>
 }}}<br>
 <br>
 Horizontal rule<br>
 ----
 <br>
 <br>
 WikiWordLink<br>
 [http://domain/page&nbsp;label]<br>
 http://domain/page<br>
 <br>
 || table || cells ||<br>
 
 </div><br>
 <a href="http://code.google.com/p/support/wiki/WikiSyntax" target="new">More
 examples</a>
 <a href="http://code.google.com/p/support/wiki/WikiSyntax" target="new"><img
 src="http://www.gstatic.com/codesite/ph/images/tearoff_icon.gif" width="16" height="16"/></a>
 </div>
 </div>
 <div class="round1"></div>
 <div class="round2"></div>
 <div class="round4"></div>
</div>
<input type="hidden" name="wikihelp" id="wikihelp" value="closed" >

 </td></tr>
 </table>
 </form>
 </div>
 
 
 

<form name="delcom" action="../w/delComment.do" method="POST">
 <input type="hidden" name="sequence_num" value="" >
 <input type="hidden" name="create_time" value="" >
 <input type="hidden" name="mode" value="" >
 <input type="hidden" name="pagename" value="WritingScenarios" >
 <input type="hidden" name="token" value="55b122417e72b952b1b3411d91b5d902" >
</form>



 <script src="http://www.gstatic.com/codesite/ph/14756227129406843427/js/prettify/prettify.js"></script>
 <script type="text/javascript">
 prettyPrint();
 </script>

<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/14756227129406843427/js/dit_scripts.js"></script>



  
 
 <script type="text/javascript" src="http://www.gstatic.com/codesite/ph/14756227129406843427/js/core_scripts_20081103.js"></script>
 <script type="text/javascript" src="/js/codesite_product_dictionary_ph.pack.04102009.js"></script>
 </div>
<div id="footer" dir="ltr">
 
 <div class="text">
 
 &copy;2010 Google -
 <a href="/projecthosting/terms.html">Terms</a> -
 <a href="http://www.google.com/privacy.html">Privacy</a> -
 <a href="/p/support/">Project Hosting Help</a>
 
 </div>
</div>

 <div class="hostedBy" style="margin-top: -20px;">
 <span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
 </div>
 
 


 
 </body>
</html>


